﻿/*******************************************************
* Copyright (c) 2018-2088, By XuXiang all rights reserved.
*
* FileName: ServerBase.cpp
* Summary: 服务模块的基类。
*
* Author: XuXiang
* Date: 2018-12-06 13:57
*******************************************************/

#include "ServerBase.h"
#include "MainBase.h"
#include "NetManagerBase.h"
#include "ModuleBase.h"
#include <assert.h>
#include <iostream>
#include "../Util/TimeUtil.h"
#include "../Util/StringUtil.h"
#include "../Config/ModuleConfig.h"

namespace Competition
{
	bool CommandInfo::Init(const string& line)
	{
		cmd.clear();
		params.clear();

		//空格分隔
		static string SP(" ");
		vector<string> splist;
		bool iscmd = true;
		StringUtil::Split(line, SP, splist);
		for (vector<string>::iterator itr = splist.begin(); itr != splist.end(); ++itr)
		{
			string e = StringUtil::Trim(*itr);
			if (e.size() > 0)
			{
				if (iscmd)
				{
					cmd = e;
					iscmd = false;
				}
				else
				{
					params.push_back(e);
				}
			}
		}

		return IsValid();
	}

	std::ostream & operator<<(std::ostream &out, const CommandInfo &info)
	{
		out << info.cmd << ":";
		for (vector<string>::const_iterator itr = info.params.cbegin(); itr != info.params.cend(); ++itr)
		{
			if (itr != info.params.cbegin())
			{
				out << ",";
			}
			out << *itr;
		}
		return out;
	}

	const Int64 ServerBase::FRAME_GAP = 1000/20;

	ServerBase::ServerBase() : m_State(ServerState::SS_CREATE), m_ID(0)
	{
	}

	ServerBase::~ServerBase()
	{
		//不能直接销毁还没结束的服务
		assert(m_State == ServerState::SS_CREATE || m_State == ServerState::SS_END);
	}

	void ServerBase::Start(int id, bool wait_init_finish)
	{
		if (m_State != ServerState::SS_CREATE)
		{
			return;
		}
		m_ID = id;
		m_Thread = thread([](ServerBase *t){t->ThreadProcess(); }, this);

		//初始完毕
		m_State = ServerState::SS_UPDATE;
		if (wait_init_finish)
		{
			m_InitSemaphore.wait();
		}
	}

	void ServerBase::Stop()
	{
		if (m_State != ServerState::SS_UPDATE)
		{
			return;
		}
		m_State = ServerState::SS_RELEASE;
		JoinThread(m_Thread);
	}

	void ServerBase::RegisterNetMessage(NetManagerBase* pMgr)
	{
		for (ModuleVector::iterator itr = m_Modules.begin(); itr != m_Modules.end(); ++itr)
		{
			(*itr)->RegisterNetMessage(pMgr);
		}
		pMgr->SetOnConnectCallBack([this](UInt64 uid) {this->OnConnect(uid); });
		pMgr->SetOnDisconnectCallBack([this](UInt64 uid) {this->OnDisconnect(uid); });
	}

	void ServerBase::RegisterStorageMessage(StorageManager* pMgr)
	{
		for (ModuleVector::iterator itr = m_Modules.begin(); itr != m_Modules.end(); ++itr)
		{
			(*itr)->RegisterStorageMessage(pMgr);
		}
	}

	void ServerBase::PostCommand(const string& cmd_line)
	{
		CommandInfo *pinfo = new CommandInfo(cmd_line);
		if (pinfo->IsValid())
		{
			m_Cmds.Push(pinfo);
		}
		else
		{
			SAFE_DELETE(pinfo);
		}
	}

	void ServerBase::OnAddConfig(vector<ModuleConfig*> &cfgs)
	{
		for (ModuleVector::iterator itr = m_Modules.begin(); itr != m_Modules.end(); ++itr)
		{
			(*itr)->AddConfig(cfgs);
		}
	}

	void ServerBase::OnUpdate()
	{
		for (ModuleVector::iterator itr = m_UpdateModules.begin(); itr != m_UpdateModules.end(); ++itr)
		{
			(*itr)->OnUpdate();
		}
	}

	void ServerBase::OnUpdatePerSecond()
	{
		for (ModuleVector::iterator itr = m_Modules.begin(); itr != m_Modules.end(); ++itr)
		{
			(*itr)->OnUpdatePerSecond();
		}
	}

	void ServerBase::OnCommand(const string& cmd, const vector<string> &param)
	{
	}

	void ServerBase::OnInitModules()
	{
	}

	void ServerBase::AddModules(ModuleBase* module)
	{
		if (module->IsEnableUpdate())
		{
			m_UpdateModules.push_back(module);
		}
		m_Modules.push_back(module);
	}

	void ServerBase::OnConnect(UInt64 uid)
	{
	}

	void ServerBase::OnDisconnect(UInt64 uid)
	{
	}

	void ServerBase::ThreadProcess()
	{
		//服务器完整周期 初始->更新->销毁
		m_State = ServerState::SS_INIT;
		Init();
		RegisterStorageMessage(MainBase::GetCurMain()->GetStorageManager());
		RegisterNetMessage(MainBase::GetCurMain()->GetNetManager());
		m_InitSemaphore.post();
		m_State = ServerState::SS_UPDATE;
		Update();			//Update函数会等m_State!=ServerState::SS_UPDATE时结束
		Release();
		m_State = ServerState::SS_END;
	}

	void ServerBase::HandleCommand()
	{
		//先进行不安全的次数只读判断
		if (m_Cmds.GetSize() <= 0)
		{
			return;
		}

		static queue<CommandInfo*> temp_queue;
		m_Cmds.MoveAll(temp_queue);

		//分发命令
		while (temp_queue.size() > 0)
		{
			CommandInfo *item = temp_queue.front();
			temp_queue.pop();
			OnCommand(item->cmd, item->params);
			SAFE_DELETE(item);
		}
	}

	void ServerBase::Init()
	{
		//创建模块
		 m_UpdateModules.clear();
		SAFE_DELETE_VECTOR(m_Modules);
		OnInitModules();

		//先初始化配置
		m_Configs.clear();
		OnAddConfig(m_Configs);
		for (vector<ModuleConfig*>::size_type i = 0; i < m_Configs.size(); ++i)
		{
			ModuleConfig* cfg = m_Configs[i];
			if (!cfg->IsInit())
			{
				cfg->Init();
			}
		}

		//再初始化模块
		for (ModuleVector::size_type i = 0; i < m_Modules.size(); ++i)
		{
			m_Modules[i]->Init();
		}
		OnInit();
		::printf("Init complete\n");
	}

	void ServerBase::Update()
	{
		NetManagerBase *pNetMgr = MainBase::GetCurMain()->GetNetManager();
		UInt64 t_sectick = TimeUtil::GetTickCount();		//秒更新开始计数
		while (m_State == ServerState::SS_UPDATE)
		{
			UInt64 t_loopstart = TimeUtil::GetTickCount();		//循环开始的时间
			pNetMgr->Dispatch();
			HandleCommand();
			OnUpdate();
			if (t_loopstart - t_sectick >= 1000)
			{
				t_sectick += 1000;
				OnUpdatePerSecond();
			}
			pNetMgr->CheckSendNotify();

			//帧停留
			UInt64 t_loopend = TimeUtil::GetTickCount();
			UInt64 use = t_loopend >= t_loopstart ? (t_loopend - t_loopstart) : 0;
			if (use < FRAME_GAP)
			{
				UInt64 t_needsleep = FRAME_GAP - use;
				chrono::milliseconds dura(t_needsleep > 0 ? t_needsleep : 1);
				this_thread::sleep_for(dura);
			}
		}
	}

	void ServerBase::Release()
	{
		//释放 子类->模块逆序->配置
		OnRelease();
		for (int i = (int)m_Modules.size() - 1; i >= 0; --i)
		{
			m_Modules[i]->Release();
		}
		for (vector<ModuleConfig*>::iterator itr = m_Configs.begin(); itr != m_Configs.end(); ++itr)
		{
			(*itr)->Release();
		}

		m_UpdateModules.clear();
		SAFE_DELETE_VECTOR(m_Modules);
		::printf("Release complete\n");
	}
}